package com.skyworth.web.order.service.impl;

import com.skyworth.utils.DataConvert;
import com.skyworth.utils.StrUtil;
import com.skyworth.web.admin.menu.domain.MenuModel;
import com.skyworth.web.admin.menu.repository.MenuRepository;
import com.skyworth.web.admin.store.repository.StoreRepository;
import com.skyworth.web.admin.table.repository.TableRepository;
import com.skyworth.web.order.domain.OrderModel;
import com.skyworth.web.order.domain.OrderNotifyModel;
import com.skyworth.web.order.domain.ParentOrderModel;
import com.skyworth.web.order.repository.OrderNotifyRepository;
import com.skyworth.web.order.repository.ParentOrderRepository;
import com.skyworth.web.order.repository.SubOrderRepository;
import com.skyworth.web.order.service.NewOrderService;
import com.skyworth.web.ordermenu.OrderMenuModel;
import com.skyworth.web.ordermenu.OrderMenuRepository;
import com.skyworth.web.ordermenu.OrderMenuService;
import com.skyworth.web.wechat.repository.TableBindRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.skyworth.web.admin.table.model.TableModel.IDLE;
import static com.skyworth.web.admin.table.model.TableModel.USEING;
import static com.skyworth.web.ordermenu.OrderMenuModel.ORDER_ITEM_REMOVED;

/**
 * Created by yuhaichao on 2016/9/27.
 */
@Service
public class NewOrderServiceImpl implements NewOrderService{

    @Autowired
    private StoreRepository storeRepository;

    @Autowired
    SubOrderRepository subOrderRepository;

    @Autowired
    ParentOrderRepository parentOrderRepository;

    @Autowired
    TableRepository tableRepository;

    @Autowired
    private OrderMenuService orderMenuService;

    @Autowired
    private TableBindRepository tableBindRepository;

    @Autowired
    private OrderMenuRepository orderMenuRepository;

    @Autowired
    private MenuRepository menuRepository;

    @Autowired
    private OrderNotifyRepository orderNotifyRepository;

    /**
     * 提交订单
     * @param orderModel
     * @param list
     * @return
     */
    @Override
    @Transactional
    public OrderModel saveOrUpdate(ParentOrderModel parentOrderModel,OrderModel orderModel, List<Map<String,Object>> list) throws  Exception{
        return save(parentOrderModel,orderModel, list);
    }

    @Override
    public OrderModel getOrderCart(String userId) {
        return subOrderRepository.getOrderCart(userId);
    }

    @Override
    public ParentOrderModel getLastByTableId(String userId) {
        return parentOrderRepository.getLastByTableId(userId);
    }

    @Override
    public float getOrderPrice(String userId) {
        return subOrderRepository.getOrderPrice(userId);
    }

    @Override
    public ParentOrderModel getParentOrderById(long id) {
        return parentOrderRepository.findOne(id);
    }

    @Override
    @Transactional
    public void updateOrderState(String userId,long tableId,String subOrderIds[]) {
        List<Long> subOrderIdLong = new ArrayList<>();
        if(subOrderIds!=null && subOrderIds.length>0){
            for(String oid : subOrderIds){
                long idl=Long.parseLong(oid);
                subOrderIdLong.add(idl);
            }
        }

        List<Long> currentOrderIds =parentOrderRepository.getCurrentTableNoPaySubOrderId(userId);
        List<Long> noContains = new ArrayList<>();
        if(currentOrderIds!=null) {
            for (int i=0;i<currentOrderIds.size();i++) {
                Long oid=Long.parseLong(String.valueOf(currentOrderIds.get(i)));
                if (!subOrderIdLong.contains(oid)) {
                    noContains.add(oid);
                }
            }
        }

        System.out.println("noContains:"+noContains);

        float noPayPrice = 0;
        if(noContains.size()>0) {
            noPayPrice = subOrderRepository.getNoPayPriceByIds(noContains);
        }

        if(noContains.size()==0 || noPayPrice<=0) {
            parentOrderRepository.updateOrderState(userId);
            ParentOrderModel parentOrderModel = parentOrderRepository.getParentOrderByTableId(userId);
            subOrderRepository.updateOrderState(userId);
            tableRepository.updateTableState(tableId);
            tableBindRepository.unbindTable(tableId);

            OrderNotifyModel orderNotifyModel = new OrderNotifyModel();
            orderNotifyModel.setOrderId(parentOrderModel.getId());
            orderNotifyModel.setType(2);
            orderNotifyRepository.save(orderNotifyModel);

        }else{
            System.out.println("part pay..");
            subOrderRepository.updateOrderStateByIds(subOrderIdLong);
            ParentOrderModel parentOrderModel = parentOrderRepository.getLastByTableId(userId);
            OrderNotifyModel orderNotifyModel = new OrderNotifyModel();
            orderNotifyModel.setOrderId(parentOrderModel.getId());
            orderNotifyModel.setType(2);
            orderNotifyRepository.save(orderNotifyModel);
        }
    }

    @Override
    public Map<String,Object> getCurrentTableNoPayOrder(String userId) {
        Object obj = parentOrderRepository.getCurrentTableNoPayOrder(userId);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        Map<String,Object> map = DataConvert.objectConvertMap(obj,keyArr);
        return map;
    }

    @Override
    public Map<String, Object> getUserHistoryOrder(String userId, int page, int pagesize) {
        int startNumber=page*pagesize;
        int endNumber=pagesize;
        long total = parentOrderRepository.getUserHistoryOrderTotal(userId);
        List<Object> objList = parentOrderRepository.getUserHistoryOrder(userId,startNumber,endNumber);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        List<Map<String,Object>> list = DataConvert.objectListConvertMapList(objList,keyArr);
        Map<String,Object> map = new HashMap<>();
        map.put("total",total);
        map.put("result",list);
        return map;
    }

    @Override
    public Map<String, Object> getStoreNopayOrder(long storeId, int page, int pagesize) {
        int startNumber=page*pagesize;
        int endNumber=pagesize;
        long total = parentOrderRepository.getStoreNopayOrderTotal(storeId);
        List<Object> objList = parentOrderRepository.getStoreNopayOrder(storeId,startNumber,endNumber);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        List<Map<String,Object>> list = DataConvert.objectListConvertMapList(objList,keyArr);
        Map<String,Object> map = new HashMap<>();
        map.put("total",total);
        map.put("result",list);
        return map;
    }

    @Override
    public Map<String, Object> getStoreConfirmOrder(long storeId, int page, int pagesize) {
        int startNumber=page*pagesize;
        int endNumber=pagesize;
        Object updateDate = parentOrderRepository.getLastUpdateDate();
        String lastUpdateDate = (String) updateDate;
        long total = parentOrderRepository.getStoreConfirmOrderTotal(storeId);
        List<Object> objList = parentOrderRepository.getStoreConfirmOrder(storeId,startNumber,endNumber);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        List<Map<String,Object>> list = DataConvert.objectListConvertMapList(objList,keyArr);
        Map<String,Object> map = new HashMap<>();
        map.put("total",total);
        map.put("result",list);
        map.put("lastUpdateDate",lastUpdateDate);
        return map;
    }

    @Override
    public Map<String, Object> getSubOrderById(long subOrderId) {
        Object obj = subOrderRepository.getSubOrderById(subOrderId);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        Map<String,Object> map = DataConvert.objectConvertMap(obj,keyArr);
        return map;
    }

    @Override
    public Map<String, Object> getParentOrderDetail(long parentOrderId) {
        Object obj = parentOrderRepository.getParentOrderDetail(parentOrderId);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        Map<String,Object> map = DataConvert.objectConvertMap(obj,keyArr);
        return map;
    }

    @Override
    public Map<String, Object> getParentPayOrderDetail(long parentOrderId) {
        Object obj = parentOrderRepository.getParentPayOrderDetail(parentOrderId);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        Map<String,Object> map = DataConvert.objectConvertMap(obj,keyArr);
        return map;
    }

    @Override
    public Map<String, Object> getParentNoPayOrderDetail(long parentOrderId) {
        Object obj = parentOrderRepository.getParentNoPayOrderDetail(parentOrderId);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        Map<String,Object> map = DataConvert.objectConvertMap(obj,keyArr);
        return map;
    }



    @Override
    @Transactional
    public void refuseOrder(Long id) {
        subOrderRepository.setOrderState(id,ORDER_WAITER_REFUSE);
        OrderModel orderModel = subOrderRepository.findOne(id);
                Object obj = parentOrderRepository.getCurrentTableNoPayOrder(orderModel.userId);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        Map<String,Object> map = DataConvert.objectConvertMap(obj,keyArr);
        if(map==null) {
            //台桌状态改为空闲状态
            tableRepository.setTableStateByOrderId(id, IDLE);
        }

        OrderNotifyModel orderNotifyModel = new OrderNotifyModel();
        orderNotifyModel.setOrderId(id);
        orderNotifyModel.setType(1);

        orderNotifyRepository.save(orderNotifyModel);

    }

    @Override
    @Transactional
    public OrderModel acceptOrder(Long id) {
        subOrderRepository.setOrderState(id, ORDER_CONFIRMED);
        OrderModel orderModel = subOrderRepository.findOne(id);
        if(orderModel!=null) {
            ParentOrderModel pom = parentOrderRepository.getLastByTableId(orderModel.userId);
            long pid=0;
            if (pom != null && pom.getId() > 0) {
                orderModel.parentId=pom.getId();
                pid = pom.getId();
                parentOrderRepository.setOrderState(orderModel.parentId, ORDER_CONFIRMED);
            }else{
                pom = new ParentOrderModel();
                pom.setStoreId(orderModel.storeId);
                pom.setTableId(orderModel.tableId);
                pom.setPeople(orderModel.people);
                pom.setState(NewOrderService.ORDER_CONFIRMED);
                pom = parentOrderRepository.save(pom);
                pid = pom.getId();
            }
            orderModel.parentId=pid;
            subOrderRepository.save(orderModel);
            //parentOrderRepository.setOrderState(orderModel.parentId, ORDER_CONFIRMED);
            //台桌状态改为使用状态
            tableRepository.setTableStateByOrderId(id, USEING);

            OrderNotifyModel orderNotifyModel = new OrderNotifyModel();
            orderNotifyModel.setOrderId(id);
            orderNotifyModel.setType(1);

            OrderNotifyModel orderNotifyModel1 = new OrderNotifyModel();
            orderNotifyModel1.setOrderId(orderModel.parentId);
            orderNotifyModel1.setType(2);
            List<OrderNotifyModel> orderNotifyList = new ArrayList<>();
            orderNotifyList.add(orderNotifyModel);
            orderNotifyList.add(orderNotifyModel1);
            orderNotifyRepository.save(orderNotifyList);
        }

        return orderModel;
    }


    /**
     * 服务员退菜
     * @param itemId 要删除项，在 ff_map_order_menu中的id
     * @return
     */
    @Override
    @Transactional
    public OrderModel removeMenuItem(Long itemId) {

        OrderMenuModel orderMenuModel = orderMenuRepository.findOne(itemId);
        orderMenuModel.removeFlag = ORDER_ITEM_REMOVED;
        //修改removeFlag为1，即软删除
        orderMenuModel = orderMenuRepository.save(orderMenuModel);

        //订单价格修改
        MenuModel menuModel = menuRepository.findOne(orderMenuModel.menuId);
        float price = menuModel.unitPrice * orderMenuModel.count;
        //优惠的价格--折扣价
        if(menuModel.discount != 10){
            price *= menuModel.discount * 0.1;
        }

        OrderModel orderModel = subOrderRepository.findOne(orderMenuModel.orderId);
        orderModel.price -= price;
        orderModel.originalPrice -= menuModel.unitPrice;

        // 转化为保留小数点后一位
        orderModel.price = toPointOne(orderModel.price);
        orderModel.originalPrice = toPointOne(orderModel.originalPrice);
        //更新数据库
        orderModel = subOrderRepository.save(orderModel);

        Object obj =parentOrderRepository.getParentNoPayOrderDetail(orderModel.parentId);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        Map<String,Object> map = DataConvert.objectConvertMap(obj,keyArr);

        //orderModel.price=0;
        if(map==null || map.get("price")==null || Float.parseFloat(StrUtil.objectToString(map.get("price")))<=0){
            subOrderRepository.waiterDeleteSubOrder(orderModel.parentId);
            parentOrderRepository.waiterDeleteParentOrder(orderModel.parentId);
            tableRepository.updateTableState(orderModel.tableId);
        }/*else{
            orderModel.price=Float.parseFloat(StrUtil.objectToString(map.get("price")));
        }*/

        OrderNotifyModel orderNotifyModel = new OrderNotifyModel();
        orderNotifyModel.setOrderId(orderModel.parentId);
        orderNotifyModel.setType(2);

        orderNotifyRepository.save(orderNotifyModel);

        return orderModel;
    }

    @Override
    @Transactional
    public void deleteOrder(long parentOrderId) {
        subOrderRepository.deleteSubOrder(parentOrderId);
        parentOrderRepository.deleteParentOrder(parentOrderId);
    }

    @Override
    @Transactional
    public void waiterDeleteOrder(long parentOrderId) {
        subOrderRepository.waiterDeleteSubOrder(parentOrderId);
        parentOrderRepository.waiterDeleteParentOrder(parentOrderId);
    }

    @Override
    @Transactional
    public void offlinePay(long parentOrderId, String userId) {
        subOrderRepository.offlineSubOrderPay(parentOrderId);
        parentOrderRepository.offlineParentOrderPay(parentOrderId,userId);
        ParentOrderModel parentOrderModel = parentOrderRepository.findOne(parentOrderId);
                tableRepository.updateTableState(parentOrderModel.getTableId());
        tableBindRepository.unbindTable(parentOrderModel.getTableId());

        OrderNotifyModel orderNotifyModel = new OrderNotifyModel();
        orderNotifyModel.setOrderId(parentOrderModel.getId());
        orderNotifyModel.setType(2);
        orderNotifyRepository.save(orderNotifyModel);
    }

    @Override
    public OrderModel qrySubOrderState(long subOrderId) {
        return subOrderRepository.findOne(subOrderId);
    }

    @Override
    public Map<String, Object> getOrderNotifyList(long storeId,String lastUpdateDate) {
        Map<String,Object> map = new HashMap<>();

        Object updateDate = parentOrderRepository.getLastUpdateDate();
        String lastDate = (String) updateDate;
        List<OrderNotifyModel> notifyList = orderNotifyRepository.getLastByTableId(lastUpdateDate);
        if(notifyList==null || notifyList.size()<=0){
            map.put("lastUpdateDate",lastDate);
        }else{
            map.put("lastUpdateDate",lastDate);
            List<Long> confirmOrderId = new ArrayList<>();
            List<Long> acceptOrderId = new ArrayList<>();
            for(int i=0;i<notifyList.size();i++){
                int type = notifyList.get(i).getType();
                long id = notifyList.get(i).getOrderId();
                if(1== type){
                    confirmOrderId.add(id);
                }else if(2 ==type){
                    acceptOrderId.add(id);
                }
            }

            if(confirmOrderId.size()>0){
                List<Object> objList = parentOrderRepository.getStoreConfirmOrderUpdate(storeId,confirmOrderId);
                String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
                List<Map<String,Object>> confirmList = DataConvert.objectListConvertMapList(objList,keyArr);
                if(confirmList!=null && confirmList.size()>0){
                    map.put("confirmOrderList",confirmList);
                }
            }

            if(acceptOrderId.size()>0){
                List<Object> objList = parentOrderRepository.getStoreNopayOrderUpdate(storeId,acceptOrderId);
                String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
                List<Map<String,Object>> acceptList = DataConvert.objectListConvertMapList(objList,keyArr);
                if(acceptList!=null && acceptList.size()>0){
                    map.put("nopayOrderList",acceptList);
                }
            }

        }
        return map;
    }

    @Override
    public List<Map<String, Object>> getWechatTableConfirmOrder(String userId) {
        List<Object> objList = parentOrderRepository.getWechatTableConfirmOrder(userId);
        String[] keyArr = {"storeName","orderId","people","tableName","createDate","originalPrice","price","storeId","tableId","userId","state"};
        List<Map<String,Object>> list = DataConvert.objectListConvertMapList(objList,keyArr);
        return list;
    }

    @Override
    public List<Long> getCurrentTableNoPaySubOrderId(String userId) {
        return parentOrderRepository.getCurrentTableNoPaySubOrderId(userId);
    }

    @Override
    public Map<String, Object> getTodayZbData(long storeId,List<Integer> fromsList,List<Integer> stateList) {
        Object obj = parentOrderRepository.getTodayZbData(storeId,fromsList,stateList);
        String[] keyArr = {"peopleTotal","menuTotal","priceTotal"};
        Map<String,Object> map = DataConvert.objectConvertMap(obj,keyArr);
        if(map!=null && map.get("peopleTotal")!=null && map.get("priceTotal")!=null){
            int peopleTotal = Integer.parseInt(StrUtil.objectToString(map.get("peopleTotal")));
            float priceTotal = Float.parseFloat(StrUtil.objectToString(map.get("priceTotal")));
            int avgPrice = (int) (priceTotal/peopleTotal);
            map.put("avgPrice",avgPrice);
        }
        return map;
    }

    @Override
    public List<Map<String, Object>> getTodayTopMenuData(long storeId,List<Integer> fromsList,List<Integer> stateList) {
        List<Object> objList = parentOrderRepository.getTodayTopMenuData(storeId,fromsList,stateList);
        String[] keyArr = {"menuId","menuName","price","menuTotal"};
        List<Map<String,Object>> list = DataConvert.objectListConvertMapList(objList,keyArr);
        return list;
    }

    @Override
    public List<Map<String, Object>> getTodayOrderListData(long storeId,List<Integer> fromsList,List<Integer> stateList) {
        List<Object> objList = parentOrderRepository.getTodayOrderListData(storeId,fromsList,stateList);
        String[] keyArr = {"parentId","people","froms","state","createDate","priceTotal","originalPriceTotal","menuTotal"};
        List<Map<String,Object>> list = DataConvert.objectListConvertMapList(objList,keyArr);
        if(list!=null && list.size()>0){
            for(int i=0;i<list.size();i++){
                Map<String,Object> map = list.get(i);
                String froms = StrUtil.objectToString(map.get("froms"));
                String state = StrUtil.objectToString(map.get("state"));
                float priceTotal = Float.parseFloat(StrUtil.objectToString(map.get("priceTotal")));
                float originalPriceTotal = Float.parseFloat(StrUtil.objectToString(map.get("originalPriceTotal")));

                float diffPiiceTotal = originalPriceTotal-priceTotal;
                map.put("diffPiiceTotal",diffPiiceTotal);
                if("1".equals(froms)){
                    map.put("froms","服务员端");
                }else{
                    map.put("froms","微信端");
                }

                if("1".equals(state)){
                    map.put("state","微信支付");
                }else{
                    map.put("state","线下支付");
                }
                list.set(i,map);
            }
        }
        return list;
    }

    /**
     * 转换为一位小数点的float类型
     * @param f
     * @return
     */
        private float toPointOne(float f){
        if(f == Math.floor(f)){ //小数点后面为0 ，在去掉0
            return f;
        }else{
            return Math.round(f * 10) / 10;
        }
    }

    @Override
    public Map<String,Object> getTableUpdateList(long storeId, String updateDate) {
        Object updateDateObj = parentOrderRepository.getLastUpdateDate();
        String lastDate = (String) updateDateObj;
        List<Object> objList = null;
        if(updateDate==null || "".equals(updateDate)){
            objList = parentOrderRepository.getTableAllList(storeId);
        }else {
            objList = parentOrderRepository.getTableUpdateList(storeId, updateDate);
        }
        String[] keyArr = {"id","name","state","seating"};
        List<Map<String,Object>> tableList = DataConvert.objectListConvertMapList(objList,keyArr);
        if(tableList == null){
            tableList = new ArrayList<>();
        }
        Map<String,Object> map = new HashMap<>();
        map.put("lastUpdateDate",lastDate);
        map.put("tableList",tableList);
        return map;
    }

    @Override
    public Map<String, Object> getCurrentUpdateDate() {
        Object updateDateObj = parentOrderRepository.getLastUpdateDate();
        String lastDate = (String) updateDateObj;
        Map<String,Object> map = new HashMap<>();
        map.put("lastUpdatedate",lastDate);
        return map;
    }


    private OrderModel save(ParentOrderModel parentOrderModel, OrderModel orderModel, List<Map<String, Object>> list) throws  Exception{
        if(orderModel!=null && orderModel.userId!=null && !"".equals(orderModel.userId)){
            OrderModel subOrderModel = null;
            if(orderModel.state== NewOrderService.ORDER_CART) {
                subOrderRepository.deleteOrderCart(orderModel.userId);
                subOrderModel = subOrderRepository.save(orderModel);
            }else{
                if(parentOrderModel!=null) {
                    ParentOrderModel pom = parentOrderRepository.getLastByTableId(parentOrderModel.getUserId());
                    if(pom!=null && pom.getId()>0){
                        orderModel.parentId=pom.getId();
                        if(parentOrderModel.getPeople()>0){
                            pom.setPeople(parentOrderModel.getPeople());
                            if(orderModel.state== NewOrderService.ORDER_CONFIRMED) {
                                pom.setState(parentOrderModel.getState());
                            }
                            pom = parentOrderRepository.save(pom);
                        }
                    }else{
                        if(orderModel.state== NewOrderService.ORDER_CONFIRMED){
                            parentOrderModel.setFroms(1);
                        }
                        pom = parentOrderRepository.save(parentOrderModel);
                        orderModel.parentId=pom.getId();
                    }
                    subOrderModel = subOrderRepository.save(orderModel);
                    if(orderModel.state== NewOrderService.ORDER_CONFIRMED) {
                        tableRepository.updateTableOrderState(pom.getTableId());
                        OrderNotifyModel orderNotifyModel = new OrderNotifyModel();
                        orderNotifyModel.setOrderId(pom.getId());
                        orderNotifyModel.setType(2);
                        orderNotifyRepository.save(orderNotifyModel);
                    }else if(orderModel.state==NewOrderService.ORDER_UNCONFIRMED){
                        OrderNotifyModel orderNotifyModel = new OrderNotifyModel();
                        orderNotifyModel.setOrderId(subOrderModel.id);
                        orderNotifyModel.setType(1);
                        orderNotifyRepository.save(orderNotifyModel);
                    }
                }else{
                    throw new Exception();
                }
            }

            List<OrderMenuModel> insertModels = new ArrayList<>();
            for(Map<String,Object> item : list){
                OrderMenuModel insertItem = new OrderMenuModel();
                insertItem.orderId = subOrderModel.id;
                insertItem.menuId = Integer.parseInt(item.get("menuId").toString());
                insertItem.count = Integer.parseInt(item.get("count").toString());
                insertModels.add(insertItem);
            }

            orderMenuService.saveItems(insertModels);

            return subOrderModel;
        }




        return null;
    }
}
